package com.lightsaber.trade.cloth.web.endorsement;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.apache.struts2.convention.annotation.Namespace;
import org.apache.struts2.convention.annotation.Result;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springside.modules.orm.Page;
import org.springside.modules.utils.web.struts2.Struts2Utils;

import com.lightsaber.trade.core.entity.BaseEntity;
import com.lightsaber.trade.core.web.BaseAction;
import com.lightsaber.trade.cloth.entity.planning.AddResourceGroup;
import com.lightsaber.trade.cloth.entity.planning.AddResourceGroupItem;
import com.lightsaber.trade.cloth.entity.planning.AdminDuty;
import com.lightsaber.trade.cloth.entity.planning.Level2Planning;
import com.lightsaber.trade.cloth.entity.planning.Level3Planning;
import com.lightsaber.trade.cloth.entity.planning.Planning;
import com.lightsaber.trade.cloth.entity.planning.PlanningLevel;
import com.lightsaber.trade.cloth.entity.planning.ProgrammePlanningItem;
import com.lightsaber.trade.cloth.entity.planning.ResourceGroup;
import com.lightsaber.trade.cloth.entity.planning.ResourceGroupItem;
import com.lightsaber.trade.cloth.entity.planning.ResourceGroupPage;
import com.lightsaber.trade.cloth.service.category.CategoryService;
import com.lightsaber.trade.cloth.service.param.ParamService;
import com.lightsaber.trade.cloth.service.planning.AdminDutyService;
import com.lightsaber.trade.cloth.service.planning.Level2BreakDownService;
import com.lightsaber.trade.cloth.service.planning.Level2PlanningService;
import com.lightsaber.trade.cloth.service.planning.Level3PlanningService;
import com.lightsaber.trade.cloth.service.planning.PlanningService;
import com.lightsaber.trade.cloth.service.planning.ProgrammePlanningItemService;
import com.lightsaber.trade.cloth.service.planning.ResourceGroupItemService;
import com.lightsaber.trade.cloth.service.planning.ResourceGroupService;

@Namespace("/endorsement")
@Result(name = "SELECT-FIRST-LEVEL", location = "select-first-level-to-endorse.action?no-decorate&planningId=${planningId}", type = "redirect")
public class EndorsementAction extends BaseAction {

    private static final long serialVersionUID = -4060190468372706185L;

    @Value(value = "#{appProperties['endorsement.page.size']}")
    private String PAGE_SIZE;
    public static final String SUCESSFULLY = "<Grid><IO Result='0'/></Grid>";

    private Page<Planning> page;

    @Autowired
    private transient Level3PlanningService level3Service;
    @Autowired
    private transient Level2PlanningService level2Service;
    @Autowired
    private transient ParamService paramService;

    @Autowired
    private PlanningService planningService;

    @Autowired
    private transient ProgrammePlanningItemService ppiService;
    @Autowired
    private CategoryService categoryService;

    @Autowired
    private transient ResourceGroupService resourceGroupService;
    @Autowired
    private transient ResourceGroupItemService resourceGroupItemService;
    @Autowired
    private transient Level2BreakDownService breakDownService;

    @Autowired
    private transient AdminDutyService adminDutyService;

    private Integer planningExercise;

    private PlanningLevel planningLevel;
    private String planningId;
    private Level3Planning level3Planning;
    private Level2Planning level2Planning;

    private String studyMode;
    private String campus;
    private String department;

    private String programmePlanningItemId;
    private String viewDetailData;

    private String dutyId;
    private String curriculumHours;
    private String level1Status;

    private String categoryNodeId;
    private String programmeCode;
    private String searchByInService;

    private ResourceGroupPage resourceGroupPage;

    private ProgrammePlanningItem ppi;

    private String search;

    @Override
    public String execute() throws Exception {

        return clear();
    }

    public String search() throws Exception {

        if (StringUtils.isBlank(search)) {
            return SUCCESS;
        }

        if (page == null) {
            page = new Page<Planning>(Integer.valueOf(PAGE_SIZE));
        } else {
            page.setPageSize(Integer.valueOf(PAGE_SIZE));
        }

        if (!page.isOrderBySetted()) {
            page.setOrderBy(BaseEntity.ID);
            page.setOrder(Page.ASC);
        }

        planningService.search(planningExercise, planningLevel, page);

        return SUCCESS;
    }

    public String clear() throws Exception {
        planningExercise = null;
        planningLevel = null;

        return SUCCESS;
    }

    public String turnToEditPage() {
        Planning planning = planningService.findById(planningId);
        if (planning.getPlanningLevel() == PlanningLevel.FirstLevel) {

            return "SELECT-FIRST-LEVEL";

        } else if (planning.getPlanningLevel().equals(PlanningLevel.ThirdLevel)) {
            level3Planning = planning.getLevel3Planning();
            return "plan-third-input";

        } else if (planning.getPlanningLevel().equals(PlanningLevel.SecondLevel)) {
            level2Planning = planning.getLevel2Planning();
            Planning planning2 = planningService.findByCategoryIdAndPlanningLevel(level2Planning
                    .getPlanning().getCategory().getId(), PlanningLevel.FirstLevel);

            if (planning2 != null) {

                setLevel1Status(planning2.getStatus().getLabel());

            }
            return "plan-second-input";
        }
        return null;
    }

    public String saveBreakDown() {

        breakDownService.saveBreakDownList(ppi);
        setPpi(ppiService.get(ppi.getId()));
        addActionMessage(getText(PROCESSED_SUCCESS));
        return "plan-second-break-down";

    }

    public String turnToBreakDownPage() {
        ppi = ppiService.get(programmePlanningItemId);
        setPpi(ppi);
        return "plan-second-break-down";
    }

    public String saveLevel2Detail() throws Exception {
        level2Service.saveViewDetail(viewDetailData);
        Struts2Utils.renderXml(SUCESSFULLY);
        addActionMessage(getText(PROCESSED_SUCCESS));
        return null;
    }

    public String getLevel2Detail() {
        viewDetailData = level2Service.getViewDetail(null, level2Planning.getId(), categoryNodeId,
                searchByInService, true);
        viewDetailData = viewDetailData.replace("(Break Down)",
                "&lt;br/&gt; Break &lt;br/&gt;Down ");
        Struts2Utils.renderXml(viewDetailData);
        return null;

    }

    public String viewLevel2Detail() {
        level2Planning = level2Service.findById(level2Planning.getId());
        setLevel2Planning(level2Planning);
        setCategoryNodeId(categoryNodeId);
        setSearchByInService(searchByInService);
        return "plan-second-view-detail";
    }

    public String endorseLevel2() {
        try {
            level2Service.endorseLevel2(level2Planning.getId());
            addActionMessage(getText(PROCESSED_SUCCESS));
        } catch (Exception e) {
            addActionError(e.getMessage());
        }
        // planningId = level2Planning.getPlanning().getId();
        return turnToEditPage();
    }

    public void loadLevel2Tree() {
        String str = level2Service.loadLevel2TreeByLevel1Status(level2Planning.getId(), null);
        Struts2Utils.renderXml(str);
    }

    public String endorseLevel3() {
        String str = level3Service.endorseLevel3(level3Planning.getId());
        addActionMessage(str);
        planningId = level3Planning.getPlanning().getId();
        addActionMessage(getText(PROCESSED_SUCCESS));
        return turnToEditPage();
    }

    public String toViewLevel3Detail() {
        setLevel3Planning(level3Planning);
        setStudyMode(studyMode);
        setCampus(campus);
        setDepartment(department);
        return "plan-third-view-detail";
    }

    public void getViewLevel3DetailData() throws Exception {
        String str = level3Service.getViewDetail(level3Planning.getId(), studyMode, campus,
                department, true);
        str = str.replace("(Resource Group)", "&lt;br/&gt;Resource &lt;br/&gt;Group");
        str = str.replace("(Total Curriculum Hours)",
                "Total &lt;br/&gt;Curriculum &lt;br/&gt;Hours");
        str = str.replace("(Total Planned Hours)", "Total &lt;br/&gt;Planned &lt;br/&gt;Hours");
        Struts2Utils.renderXml(str);
    }

    public void saveViewDetail() {
        level3Service.saveViewDetail(viewDetailData);
        Struts2Utils.renderXml(SUCESSFULLY);
    }

    public String turnToAddResourcePage() {
        AdminDuty adminDuty = adminDutyService.findById(dutyId);
        resourceGroupPage = new ResourceGroupPage();
        resourceGroupPage.setDuty(String.valueOf(adminDuty.getDuty()));
        resourceGroupPage.setCurriculumHours(curriculumHours);
        resourceGroupPage.setLevel3PlanningId(level3Planning.getId());
        resourceGroupPage.setProgrammePlanningItemId(programmePlanningItemId);
        resourceGroupPage.setCampus(adminDuty.getOperatingCampus());
        resourceGroupPage.setDepartment(adminDuty.getOperatingUnit());
        List<ResourceGroup> list = resourceGroupService.findByLeve3IdAndProgrammePlanningId(
                level3Planning.getId(), programmePlanningItemId);
        List<AddResourceGroup> argsList = new ArrayList<AddResourceGroup>();
        for (ResourceGroup rg : list) {
            AddResourceGroup arg = new AddResourceGroup();
            arg.setName(rg.getName());
            arg.setPlace(String.valueOf(rg.getPlace()));
            arg.setId(rg.getId());
            List<ResourceGroupItem> rgiList = rg.getResourceGroupItems();
            List<AddResourceGroupItem> argisList = new ArrayList<AddResourceGroupItem>();
            for (ResourceGroupItem rgi : rgiList) {
                AddResourceGroupItem argi = new AddResourceGroupItem();
                argi.setCurriculumHours(String.valueOf(rgi.getCurriculumHours()));
                argi.setDistribution(String.valueOf(rgi.getDistribution()));
                argi.setServingCampus(rgi.getServingCampus());
                argi.setServingDept(rgi.getServingDept());
                argisList.add(argi);
            }
            arg.setResourceGroupItems(argisList);
            argsList.add(arg);
        }
        resourceGroupPage.setResourceGroups(argsList);
        if (argsList.isEmpty()) {
            resourceGroupPage.setResourceGroupSize(0);
        } else {
            resourceGroupPage.setResourceGroupSize(argsList.size());
        }
        setResourceGroupPage(resourceGroupPage);

        return "plan-third-resource-group";
    }

    public String saveResourceGroup() {
        resourceGroupService.saveResourceGroupList(resourceGroupPage);
        List<ResourceGroup> list = resourceGroupService.findByLeve3IdAndProgrammePlanningId(
                resourceGroupPage.getLevel3PlanningId(),
                resourceGroupPage.getProgrammePlanningItemId());
        List<AddResourceGroup> argsList = new ArrayList<AddResourceGroup>();
        for (ResourceGroup rg : list) {
            AddResourceGroup arg = new AddResourceGroup();
            arg.setName(rg.getName());
            arg.setPlace(String.valueOf(rg.getPlace()));
            arg.setId(rg.getId());
            List<ResourceGroupItem> rgiList = resourceGroupItemService.findByResourceGroupId(rg
                    .getId());
            List<AddResourceGroupItem> argisList = new ArrayList<AddResourceGroupItem>();
            for (ResourceGroupItem rgi : rgiList) {
                AddResourceGroupItem argi = new AddResourceGroupItem();
                argi.setCurriculumHours(String.valueOf(rgi.getCurriculumHours()));
                argi.setDistribution(String.valueOf(rgi.getDistribution()));
                argi.setServingCampus(rgi.getServingCampus());
                argi.setServingDept(rgi.getServingDept());
                argisList.add(argi);
            }
            arg.setResourceGroupItems(argisList);
            argsList.add(arg);
        }
        resourceGroupPage.setResourceGroups(argsList);
        if (argsList.isEmpty()) {
            resourceGroupPage.setResourceGroupSize(0);
        } else {
            resourceGroupPage.setResourceGroupSize(argsList.size());
        }
        setResourceGroupPage(resourceGroupPage);

        addActionMessage(getText(PROCESSED_SUCCESS));

        return "plan-third-resource-group";

    }

    public Page<Planning> getPage() {
        return page;
    }

    public void setPage(final Page<Planning> page) {
        this.page = page;
    }

    public void setPlanningService(final PlanningService planningService) {
        this.planningService = planningService;
    }

    public Integer getPlanningExercise() {
        return planningExercise;
    }

    public void setPlanningExercise(final Integer planningExercise) {
        this.planningExercise = planningExercise;
    }

    public PlanningLevel getPlanningLevel() {
        return planningLevel;
    }

    public void setPlanningLevel(final PlanningLevel planningLevel) {
        this.planningLevel = planningLevel;
    }

    public CategoryService getCategoryService() {
        return categoryService;
    }

    public void setCategoryService(final CategoryService categoryService) {
        this.categoryService = categoryService;
    }

    public String getPlanningId() {
        return planningId;
    }

    public void setPlanningId(final String planningId) {
        this.planningId = planningId;
    }

    public Level3Planning getLevel3Planning() {
        return level3Planning;
    }

    public String getSearch() {
        return search;
    }

    public void setSearch(final String search) {
        this.search = search;
    }

    public void setLevel3Planning(final Level3Planning level3Planning) {
        this.level3Planning = level3Planning;
    }

    public Level2Planning getLevel2Planning() {
        return level2Planning;
    }

    public void setLevel2Planning(final Level2Planning level2Planning) {
        this.level2Planning = level2Planning;
    }

    public String getStudyMode() {
        return studyMode;
    }

    public void setStudyMode(final String studyMode) {
        this.studyMode = studyMode;
    }

    public String getCampus() {
        return campus;
    }

    public void setCampus(final String campus) {
        this.campus = campus;
    }

    public String getDepartment() {
        return department;
    }

    public void setDepartment(final String department) {
        this.department = department;
    }

    public ParamService getParamService() {
        return paramService;
    }

    public void setParamService(final ParamService paramService) {
        this.paramService = paramService;
    }

    public String getProgrammePlanningItemId() {
        return programmePlanningItemId;
    }

    public void setProgrammePlanningItemId(final String programmePlanningItemId) {
        this.programmePlanningItemId = programmePlanningItemId;
    }

    public String getViewDetailData() {
        return viewDetailData;
    }

    public void setViewDetailData(final String viewDetailData) {
        this.viewDetailData = viewDetailData;
    }

    public String getDutyId() {
        return dutyId;
    }

    public void setDutyId(final String dutyId) {
        this.dutyId = dutyId;
    }

    public String getCurriculumHours() {
        return curriculumHours;
    }

    public void setCurriculumHours(final String curriculumHours) {
        this.curriculumHours = curriculumHours;
    }

    public ResourceGroupPage getResourceGroupPage() {
        return resourceGroupPage;
    }

    public void setResourceGroupPage(final ResourceGroupPage resourceGroupPage) {
        this.resourceGroupPage = resourceGroupPage;
    }

    public String getLevel1Status() {
        return level1Status;
    }

    public void setLevel1Status(final String level1Status) {
        this.level1Status = level1Status;
    }

    public String getCategoryNodeId() {
        return categoryNodeId;
    }

    public void setCategoryNodeId(final String categoryNodeId) {
        this.categoryNodeId = categoryNodeId;
    }

    public String getProgrammeCode() {
        return programmeCode;
    }

    public void setProgrammeCode(final String programmeCode) {
        this.programmeCode = programmeCode;
    }

    public String getSearchByInService() {
        return searchByInService;
    }

    public void setSearchByInService(final String searchByInService) {
        this.searchByInService = searchByInService;
    }

    public ProgrammePlanningItem getPpi() {
        return ppi;
    }

    public void setPpi(final ProgrammePlanningItem ppi) {
        this.ppi = ppi;
    }

}
